

<!DOCTYPE html>
<html class="writer-html5" lang="en" >
<head>
  <meta charset="utf-8" />
  <meta name="generator" content="Docutils 0.19: https://docutils.sourceforge.io/" />

  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  
  <title>监视器故障排除 &mdash; Ceph Documentation</title>
  

  
  <link rel="stylesheet" href="../../../_static/ceph.css" type="text/css" />
  <link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" />
  <link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" />
  <link rel="stylesheet" href="../../../_static/ceph.css" type="text/css" />
  <link rel="stylesheet" href="../../../_static/graphviz.css" type="text/css" />
  <link rel="stylesheet" href="../../../_static/css/custom.css" type="text/css" />

  
  

  
  

  

  
  <!--[if lt IE 9]>
    <script src="../../../_static/js/html5shiv.min.js"></script>
  <![endif]-->
  
    
      <script type="text/javascript" id="documentation_options" data-url_root="../../../" src="../../../_static/documentation_options.js"></script>
        <script src="../../../_static/jquery.js"></script>
        <script src="../../../_static/_sphinx_javascript_frameworks_compat.js"></script>
        <script data-url_root="../../../" id="documentation_options" src="../../../_static/documentation_options.js"></script>
        <script src="../../../_static/doctools.js"></script>
        <script src="../../../_static/sphinx_highlight.js"></script>
    
    <script type="text/javascript" src="../../../_static/js/theme.js"></script>

    
    <link rel="index" title="Index" href="../../../genindex/" />
    <link rel="search" title="Search" href="../../../search/" />
    <link rel="next" title="OSD 故障排除" href="../troubleshooting-osd/" />
    <link rel="prev" title="Ceph 社区" href="../community/" /> 
</head>

<body class="wy-body-for-nav">

   
  <header class="top-bar">
    <div role="navigation" aria-label="Page navigation">
  <ul class="wy-breadcrumbs">
      <li><a href="../../../" class="icon icon-home" aria-label="Home"></a></li>
          <li class="breadcrumb-item"><a href="../../">Ceph 存储集群</a></li>
          <li class="breadcrumb-item"><a href="../../operations/">集群运维</a></li>
      <li class="breadcrumb-item active">监视器故障排除</li>
      <li class="wy-breadcrumbs-aside">
            <a href="../../../_sources/rados/troubleshooting/troubleshooting-mon.rst.txt" rel="nofollow"> View page source</a>
      </li>
  </ul>
  <hr/>
</div>
  </header>
  <div class="wy-grid-for-nav">
    
    <nav data-toggle="wy-nav-shift" class="wy-nav-side">
      <div class="wy-side-scroll">
        <div class="wy-side-nav-search"  style="background: #eee" >
          

          
            <a href="../../../" class="icon icon-home"> Ceph
          

          
          </a>

          

          
<div role="search">
  <form id="rtd-search-form" class="wy-form" action="../../../search/" method="get">
    <input type="text" name="q" placeholder="Search docs" aria-label="Search docs" />
    <input type="hidden" name="check_keywords" value="yes" />
    <input type="hidden" name="area" value="default" />
  </form>
</div>

          
        </div>

        
        <div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
          
            
            
              
            
            
              <ul class="current">
<li class="toctree-l1"><a class="reference internal" href="../../../start/">Ceph 简介</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../install/">安装 Ceph</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../cephadm/">Cephadm</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="../../">Ceph 存储集群</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="../../configuration/">配置</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../operations/">运维</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../man/">    手册页</a></li>
<li class="toctree-l2 current"><a class="reference internal" href="../">故障排除</a><ul class="current">
<li class="toctree-l3"><a class="reference internal" href="../community/">Ceph 社区</a></li>
<li class="toctree-l3"><a class="reference internal" href="../log-and-debug/">日志记录和调试</a></li>
<li class="toctree-l3 current"><a class="current reference internal" href="#">监视器故障排除</a><ul>
<li class="toctree-l4"><a class="reference internal" href="#id2">开始排障</a></li>
<li class="toctree-l4"><a class="reference internal" href="#rados-troubleshoting-troubleshooting-mon-using-admin-socket">使用监视器的管理套接字</a></li>
<li class="toctree-l4"><a class="reference internal" href="#mon-status">理解 mon_status</a></li>
<li class="toctree-l4"><a class="reference internal" href="#id4">最常见的监视器问题</a></li>
<li class="toctree-l4"><a class="reference internal" href="#id10">监视器存储故障</a></li>
<li class="toctree-l4"><a class="reference internal" href="#id14">所有尝试都失败了，怎么办？</a></li>
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="../troubleshooting-osd/">OSD 故障排除</a></li>
<li class="toctree-l3"><a class="reference internal" href="../troubleshooting-pg/">归置组排障</a></li>
<li class="toctree-l3"><a class="reference internal" href="../memory-profiling/">内存剖析</a></li>
<li class="toctree-l3"><a class="reference internal" href="../cpu-profiling/">CPU 剖析</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../../api/">APIs</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../../../cephfs/">Ceph 文件系统</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../rbd/">Ceph 块设备</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../radosgw/">Ceph 对象网关</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../mgr/">Ceph 管理器守护进程</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../mgr/dashboard/">Ceph 仪表盘</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../monitoring/">监控概览</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../api/">API 文档</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../architecture/">体系结构</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../dev/developer_guide/">开发者指南</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../dev/internals/">Ceph 内幕</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../governance/">项目管理</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../foundation/">Ceph 基金会</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../ceph-volume/">ceph-volume</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../releases/general/">Ceph 版本（总目录）</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../releases/">Ceph 版本（索引）</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../security/">Security</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../hardware-monitoring/">硬件监控</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../glossary/">Ceph 术语</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../jaegertracing/">Tracing</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../translation_cn/">中文版翻译资源</a></li>
</ul>

            
          
        </div>
        
      </div>
    </nav>

    <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">

      
      <nav class="wy-nav-top" aria-label="top navigation">
        
          <i data-toggle="wy-nav-top" class="fa fa-bars"></i>
          <a href="../../../">Ceph</a>
        
      </nav>


      <div class="wy-nav-content">
        
        <div class="rst-content">
        
          <div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
           <div itemprop="articleBody">
            
<div id="dev-warning" class="admonition note">
  <p class="first admonition-title">Notice</p>
  <p class="last">This document is for a development version of Ceph.</p>
</div>
  <div id="docubetter" align="right" style="padding: 5px; font-weight: bold;">
    <a href="https://pad.ceph.com/p/Report_Documentation_Bugs">Report a Documentation Bug</a>
  </div>

  
  <section id="rados-troubleshooting-mon">
<span id="id1"></span><h1>监视器故障排除<a class="headerlink" href="#rados-troubleshooting-mon" title="Permalink to this heading"></a></h1>
<p id="index-0">即使集群出现与监视器相关的问题，也不一定会有瘫痪的危险。
如果集群失去了多个监视器，只要有足够多活着的监视器们能形成法定人数，
集群仍能保持正常运行。</p>
<p>如果您的集群出现监视器相关问题，建议您参考以下故障排除信息。</p>
<section id="id2">
<h2>开始排障<a class="headerlink" href="#id2" title="Permalink to this heading"></a></h2>
<p>在排除 Ceph 监视器故障的过程中，首先要确保监视器正在运行，
并且能够与网络通信、并且在网络上能看到它。
按照本节中的步骤排除监视器故障的最简单起因。</p>
<ol class="arabic">
<li><p><strong>确保监视器在运行。</strong></p>
<p>确保监视器（ <em>mon</em> ）守护进程的各个进程
（ <code class="docutils literal notranslate"><span class="pre">ceph-mon</span></code> ）在运行。
有可能是升级后没有重启监视器进程。
查验这一简单的疏忽可以省去数小时艰苦的故障排除工作。</p>
<p>确保管理器守护进程（ <code class="docutils literal notranslate"><span class="pre">ceph-mgr</span></code> ）在运行也很重要。
记住，典型的集群配置为每个监视器（ <code class="docutils literal notranslate"><span class="pre">ceph-mon</span></code> ）
配备了一个管理器（ <code class="docutils literal notranslate"><span class="pre">ceph-mgr</span></code> ）。</p>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>在 v1.12.5 之前的版本中，
Rook 不会运行两个以上管理器。</p>
</div>
</li>
<li><p><strong>确保到各个监视器节点可达。</strong></p>
<p>在某些罕见的情况下， <code class="docutils literal notranslate"><span class="pre">iptables</span></code> 规则可能会拦截到监视器节点或 TCP 端口的访问。
这些规则可能是以前压力测试或开发规则时遗留下来的。
要检查是否存在这样的规则，可通过 SSH 进入每个监视器节点，
并用 <code class="docutils literal notranslate"><span class="pre">telnet</span></code> 或 <code class="docutils literal notranslate"><span class="pre">nc</span></code> 或类似工具尝试连接其他监视器节点的 <code class="docutils literal notranslate"><span class="pre">tcp/3300</span></code> 和 <code class="docutils literal notranslate"><span class="pre">tcp/6789</span></code> 端口。</p>
</li>
<li><p><strong>确保 “ceph status” 命令能运行，并收到集群回复。</strong></p>
<p>如果 <code class="docutils literal notranslate"><span class="pre">ceph</span> <span class="pre">status</span></code> 命令收到了来自集群的回复，
那就说明集群已启动并正在运行。
监视器们只有形成法定人数后才会响应 <code class="docutils literal notranslate"><span class="pre">status</span></code> 请求。
确认（ <code class="docutils literal notranslate"><span class="pre">status</span></code> 命令）报告了一个或多个 <code class="docutils literal notranslate"><span class="pre">mgr</span></code> 守护进程正在运行。
在没有缺陷的集群中， <code class="docutils literal notranslate"><span class="pre">ceph</span> <span class="pre">status</span></code> 应该报告所有 <code class="docutils literal notranslate"><span class="pre">mgr</span></code> 守护进程都在运行。</p>
<p>如果 <code class="docutils literal notranslate"><span class="pre">ceph</span> <span class="pre">status</span></code> 命令没有收到来自集群的回复，
则可能没有足够的监视器状态为 <code class="docutils literal notranslate"><span class="pre">up</span></code> 来形成法定人数。
如果运行 <code class="docutils literal notranslate"><span class="pre">ceph</span> <span class="pre">-s</span></code> 命令时没有加更多选项，
它将连接到任意选择的监视器。但在某些情况下，
在命令中加上 <code class="docutils literal notranslate"><span class="pre">-m</span></code> 标志连接到指定监视器
（或依次连接到多个指定监视器）：
例如， <code class="docutils literal notranslate"><span class="pre">ceph</span> <span class="pre">status</span> <span class="pre">-m</span> <span class="pre">mymon1</span></code> 。</p>
</li>
<li><p><strong>这些都不行，怎么办？</strong></p>
<p>如果上述解决方法没能解决你的问题，
挨个检查监视器们也许有用。即使没有达成法定人数，
也可以单独连线各监视器去询问其状态，
用 <code class="docutils literal notranslate"><span class="pre">ceph</span> <span class="pre">tell</span> <span class="pre">mon.ID</span> <span class="pre">mon_status</span></code> 命令
（其中 ID 是监视器的标识符）。</p>
<p>执行 <code class="docutils literal notranslate"><span class="pre">ceph</span> <span class="pre">tell</span> <span class="pre">mon.ID</span> <span class="pre">mon_status</span></code> 命令查询集群内的各个监视器。
关于此命令的输出详情，参阅<a class="reference internal" href="#rados-troubleshoting-troubleshooting-mon-understanding-mon-status"><span class="std std-ref">深入理解 mon_status</span></a> 。</p>
<p>还有另外一种方法单独连接各个监视器：
SSH 登录到各监视器节点、并查询那个守护进程的
admin socket （管理套接字）。参阅 <a class="reference internal" href="#rados-troubleshoting-troubleshooting-mon-using-admin-socket"><span class="std std-ref">使用监视器的管理套接字</span></a> 。</p>
</li>
</ol>
</section>
<section id="rados-troubleshoting-troubleshooting-mon-using-admin-socket">
<span id="id3"></span><h2>使用监视器的管理套接字<a class="headerlink" href="#rados-troubleshoting-troubleshooting-mon-using-admin-socket" title="Permalink to this heading"></a></h2>
<p>通过管理套接字（ admin socket ），你可以用 Unix 套接字文件直接与指定守护进程交互。这个文件位于你监视器的 <code class="docutils literal notranslate"><span class="pre">run</span></code> 目录下。</p>
<p>管理套接字默认位于 <code class="docutils literal notranslate"><span class="pre">/var/run/ceph/ceph-mon.ID.asok</span></code> 。
管理套接字的默认位置可以覆盖掉。
如果其默认位置被覆盖掉了，那么管理套接字就在别处。
集群守护进程部署在容器内时，常常出现这种情况。</p>
<p>要找出管理套接字的目录，看一下 <code class="docutils literal notranslate"><span class="pre">ceph.conf</span></code> 里是否配置了其它路径、
或者执行下列命令：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><style type="text/css">
span.prompt1:before {
  content: "$ ";
}
</style><span class="prompt1">ceph-conf<span class="w"> </span>--name<span class="w"> </span>mon.ID<span class="w"> </span>--show-config-value<span class="w"> </span>admin_socket</span>
</pre></div></div><p>只有在监视器运行时管理套接字才可用。
每次监视器正常关闭时，管理套接字会被删除；
如果监视器不运行了、但管理套接字还存在，
就说明监视器不是正常关闭的。如果监视器没在运行，
你就不能使用管理套接字，而且 <code class="docutils literal notranslate"><span class="pre">ceph</span></code> 命令会返回类似 <code class="docutils literal notranslate"><span class="pre">Error</span> <span class="pre">111:</span> <span class="pre">Connection</span> <span class="pre">Refused</span></code> 的消息。</p>
<p>要访问管理员套接字，执行 <code class="docutils literal notranslate"><span class="pre">ceph</span> <span class="pre">tell</span></code> 命令
（指定你感兴趣的守护进程）：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span class="prompt1">ceph<span class="w"> </span>tell<span class="w"> </span>mon.&lt;id&gt;<span class="w"> </span>mon_status</span>
</pre></div></div><p>此命令通过管理套接字向指定的、运行中监视器守护进程 <code class="docutils literal notranslate"><span class="pre">&lt;id&gt;</span></code> 传入 <code class="docutils literal notranslate"><span class="pre">help</span></code> 命令。
如果知道管理员套接字文件的完整路径，
可以更直接地操作，执行下列命令：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span class="prompt1">ceph<span class="w"> </span>--admin-daemon<span class="w"> </span>&lt;full_path_to_asok_file&gt;<span class="w"> </span>&lt;command&gt;</span>
</pre></div></div><p>执行 <code class="docutils literal notranslate"><span class="pre">ceph</span> <span class="pre">help</span></code> 可显示管理套接字支持的所有命令。
特别关注一下 <code class="docutils literal notranslate"><span class="pre">config</span> <span class="pre">get</span></code> 、 <code class="docutils literal notranslate"><span class="pre">config</span> <span class="pre">show</span></code> 、 <code class="docutils literal notranslate"><span class="pre">mon</span> <span class="pre">stat</span></code> 和 <code class="docutils literal notranslate"><span class="pre">quorum_status</span></code> 命令。</p>
</section>
<section id="mon-status">
<span id="rados-troubleshoting-troubleshooting-mon-understanding-mon-status"></span><h2>理解 mon_status<a class="headerlink" href="#mon-status" title="Permalink to this heading"></a></h2>
<p>监视器的状态（由 <code class="docutils literal notranslate"><span class="pre">ceph</span> <span class="pre">tell</span> <span class="pre">mon.X</span> <span class="pre">mon_status</span></code> 命令报告的）
可通过管理套接字获取。 <code class="docutils literal notranslate"><span class="pre">ceph</span> <span class="pre">tell</span> <span class="pre">mon.X</span> <span class="pre">mon_status</span></code>
命令会输出大量有关监视器的信息
（包括在 <code class="docutils literal notranslate"><span class="pre">quorum_status</span></code> 命令输出中找到的信息）。</p>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p><code class="docutils literal notranslate"><span class="pre">ceph</span> <span class="pre">tell</span> <span class="pre">mon.X</span> <span class="pre">mon_status</span></code> 命令并不意味着要按字面输入。
运行该命令时， <code class="docutils literal notranslate"><span class="pre">mon.X</span></code> 的 <code class="docutils literal notranslate"><span class="pre">X</span></code> 部分应替换为 Ceph 集群的特定值。</p>
</div>
<p>要了解此命令的输出，参考下面的示例，
我们将看到 <code class="docutils literal notranslate"><span class="pre">ceph</span> <span class="pre">tell</span> <span class="pre">mon.c</span> <span class="pre">mon_status</span></code> 的输出：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">{</span> <span class="s2">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;c&quot;</span><span class="p">,</span>
  <span class="s2">&quot;rank&quot;</span><span class="p">:</span> <span class="mi">2</span><span class="p">,</span>
  <span class="s2">&quot;state&quot;</span><span class="p">:</span> <span class="s2">&quot;peon&quot;</span><span class="p">,</span>
  <span class="s2">&quot;election_epoch&quot;</span><span class="p">:</span> <span class="mi">38</span><span class="p">,</span>
  <span class="s2">&quot;quorum&quot;</span><span class="p">:</span> <span class="p">[</span>
        <span class="mi">1</span><span class="p">,</span>
        <span class="mi">2</span><span class="p">],</span>
  <span class="s2">&quot;outside_quorum&quot;</span><span class="p">:</span> <span class="p">[],</span>
  <span class="s2">&quot;extra_probe_peers&quot;</span><span class="p">:</span> <span class="p">[],</span>
  <span class="s2">&quot;sync_provider&quot;</span><span class="p">:</span> <span class="p">[],</span>
  <span class="s2">&quot;monmap&quot;</span><span class="p">:</span> <span class="p">{</span> <span class="s2">&quot;epoch&quot;</span><span class="p">:</span> <span class="mi">3</span><span class="p">,</span>
      <span class="s2">&quot;fsid&quot;</span><span class="p">:</span> <span class="s2">&quot;5c4e9d53-e2e1-478a-8061-f543f8be4cf8&quot;</span><span class="p">,</span>
      <span class="s2">&quot;modified&quot;</span><span class="p">:</span> <span class="s2">&quot;2013-10-30 04:12:01.945629&quot;</span><span class="p">,</span>
      <span class="s2">&quot;created&quot;</span><span class="p">:</span> <span class="s2">&quot;2013-10-29 14:14:41.914786&quot;</span><span class="p">,</span>
      <span class="s2">&quot;mons&quot;</span><span class="p">:</span> <span class="p">[</span>
            <span class="p">{</span> <span class="s2">&quot;rank&quot;</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span>
              <span class="s2">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;a&quot;</span><span class="p">,</span>
              <span class="s2">&quot;addr&quot;</span><span class="p">:</span> <span class="s2">&quot;127.0.0.1:6789\/0&quot;</span><span class="p">},</span>
            <span class="p">{</span> <span class="s2">&quot;rank&quot;</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span>
              <span class="s2">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;b&quot;</span><span class="p">,</span>
              <span class="s2">&quot;addr&quot;</span><span class="p">:</span> <span class="s2">&quot;127.0.0.1:6790\/0&quot;</span><span class="p">},</span>
            <span class="p">{</span> <span class="s2">&quot;rank&quot;</span><span class="p">:</span> <span class="mi">2</span><span class="p">,</span>
              <span class="s2">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;c&quot;</span><span class="p">,</span>
              <span class="s2">&quot;addr&quot;</span><span class="p">:</span> <span class="s2">&quot;127.0.0.1:6795\/0&quot;</span><span class="p">}]}}</span>
</pre></div>
</div>
<p>输出结果显示， monmap 中有三个监视器
（ <code class="docutils literal notranslate"><span class="pre">a</span></code> 、 <code class="docutils literal notranslate"><span class="pre">b</span></code> 和 <code class="docutils literal notranslate"><span class="pre">c</span></code> ），
法定人数由两个监视器组成，并且 <code class="docutils literal notranslate"><span class="pre">c</span></code> 是 <code class="docutils literal notranslate"><span class="pre">peon</span></code> 。</p>
<p><strong>哪个监视器在法定人数之外？</strong></p>
<blockquote>
<div><p>答案是 <code class="docutils literal notranslate"><span class="pre">a</span></code> （即 <code class="docutils literal notranslate"><span class="pre">mon.a</span></code> ）。 <code class="docutils literal notranslate"><span class="pre">mon.a</span></code> 在法定人数之外。</p>
</div></blockquote>
<p><strong>在本例中，我们如何知道 mon.a 不在法定人数之列？</strong></p>
<blockquote>
<div><p>我们之所以知道 <code class="docutils literal notranslate"><span class="pre">mon.a</span></code> 不在法定人数之列，是因为它的 rank 为 <code class="docutils literal notranslate"><span class="pre">0</span></code> ，
而根据定义， rank 为 <code class="docutils literal notranslate"><span class="pre">0</span></code> 的监视器不在法定人数之列。</p>
<p>如果我们检查一下 <code class="docutils literal notranslate"><span class="pre">quorum</span></code> 集合，就会清楚地发现此集合里有两个监视器：
<code class="docutils literal notranslate"><span class="pre">1</span></code> 和 <code class="docutils literal notranslate"><span class="pre">2</span></code> ，但这些不是监视器名称。
它们是监视器的 rank ，正如当前 <code class="docutils literal notranslate"><span class="pre">monmap</span></code> 所确定的那样。
法定人数集合不包括 rank 为 <code class="docutils literal notranslate"><span class="pre">0</span></code> 的监视器，
而根据 <code class="docutils literal notranslate"><span class="pre">monmap</span></code> ，该监视器就是 <code class="docutils literal notranslate"><span class="pre">mon.a</span></code> 。</p>
</div></blockquote>
<p><strong>监视器 rank 是如何确定的？</strong></p>
<blockquote>
<div><p>每当有监视器加入或移出集群时，都会计算（或重新计算）
监视器的 rank 。 rank 的计算遵循一个简单的规则： <code class="docutils literal notranslate"><span class="pre">IP:PORT</span></code> 组合<strong>越大</strong>，
其 rank <strong>就越低</strong>。在本例中，由于 <code class="docutils literal notranslate"><span class="pre">127.0.0.1:6789</span></code> (<code class="docutils literal notranslate"><span class="pre">mon.a</span></code>)
在数值上小于其他两个 <code class="docutils literal notranslate"><span class="pre">IP:PORT</span></code> 组合（“监视器 b”的组合是 <code class="docutils literal notranslate"><span class="pre">127.0.0.1:6790</span></code>
而“监视器 c”的是 <code class="docutils literal notranslate"><span class="pre">127.0.0.1:6795</span></code> ），
因此 <code class="docutils literal notranslate"><span class="pre">mon.a</span></code> 的 rank 最高：即 rank <code class="docutils literal notranslate"><span class="pre">0</span></code> 。</p>
</div></blockquote>
</section>
<section id="id4">
<h2>最常见的监视器问题<a class="headerlink" href="#id4" title="Permalink to this heading"></a></h2>
<section id="id5">
<h3>集群存在法定人数但是挂了不止一个监视器<a class="headerlink" href="#id5" title="Permalink to this heading"></a></h3>
<p>集群达成了法定人数，但至少有一个监视器挂掉时，
<code class="docutils literal notranslate"><span class="pre">ceph</span> <span class="pre">health</span> <span class="pre">detail</span></code> 会返回类似下面的消息：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>$ ceph health detail
[snip]
mon.a (rank 0) addr 127.0.0.1:6789/0 is down (out of quorum)
</pre></div>
</div>
<p><strong>Ceph 集群存在法定人数却至少有一个监视器挂掉时，如何排查？</strong></p>
<blockquote>
<div><ol class="arabic simple">
<li><p>确认一下 <code class="docutils literal notranslate"><span class="pre">mon.a</span></code> 在运行。</p></li>
<li><p>确保可以从其他监视器节点连接到 <code class="docutils literal notranslate"><span class="pre">mon.a</span></code> 所在的节点。
同时还要检查 TCP 端口。检查所有节点上的 <code class="docutils literal notranslate"><span class="pre">iptables</span></code> 和
<code class="docutils literal notranslate"><span class="pre">nf_conntrack</span></code> ，确保没有丢弃/拒绝连接。</p></li>
</ol>
<p>如果这些初步的故障排除没有解决问题，
则需要进一步调查。</p>
<p>首先，通过管理套接字检查问题监视器的 <code class="docutils literal notranslate"><span class="pre">mon_status</span></code> ，
方法在 <a class="reference internal" href="#id3">使用监视器的管理套接字</a> 和
<a class="reference internal" href="#mon-status">理解 mon_status</a> 里介绍过了。</p>
<p>如果有个监视器不在法定人数内，那么它的状态将是以下状态之一：
<code class="docutils literal notranslate"><span class="pre">probing</span></code> 、 <code class="docutils literal notranslate"><span class="pre">electing</span></code> 或 <code class="docutils literal notranslate"><span class="pre">synchronizing</span></code> 。
如果监视器的状态是 <code class="docutils literal notranslate"><span class="pre">leader</span></code> 或 <code class="docutils literal notranslate"><span class="pre">peon</span></code> ，那么这个监视器认为自己在法定人数中，但集群的其余部分认为它不在法定人数中。
处于 <code class="docutils literal notranslate"><span class="pre">probing</span></code> 、 <code class="docutils literal notranslate"><span class="pre">electing</span></code> 或 <code class="docutils literal notranslate"><span class="pre">synchronizing</span></code> 状态的监视器有可能在故障排除过程中就已经进入了法定人数。
在故障排除期间，再次检查 <code class="docutils literal notranslate"><span class="pre">ceph</span> <span class="pre">status</span></code> ，
以确定监视器是否已进入了法定人数。
如果监视器仍然在法定人数之外，
那就继续进行本节文档所述的排查。</p>
</div></blockquote>
<p><strong>监视器状态为 ``probing`` 时，是什么意思？</strong></p>
<blockquote>
<div><p>如果 <code class="docutils literal notranslate"><span class="pre">ceph</span> <span class="pre">health</span> <span class="pre">detail</span></code> 显示监视器的状态为 <code class="docutils literal notranslate"><span class="pre">probing</span></code> ，
表示这个监视器仍在寻找其他监视器。
每个监视器在启动时都会保持这种状态一段时间。
当监视器连接到 <code class="docutils literal notranslate"><span class="pre">monmap</span></code> 中指定的其他监视器后，
就不再处于 <code class="docutils literal notranslate"><span class="pre">probing</span></code> 状态。监视器处于
<code class="docutils literal notranslate"><span class="pre">probing</span></code> 状态的时间长短取决于其所在集群的参数。
例如，当监视器是单监视器集群的一部分时
（在生产环境中切勿这样做），监视器几乎会瞬间通过 probing 状态。
在多监视器集群中，监视器会一直处于 <code class="docutils literal notranslate"><span class="pre">probing</span></code> 状态，
直到找到足够的监视器能形成法定人数为止，
这意味着如果集群的三个监视器中有两个 <code class="docutils literal notranslate"><span class="pre">down</span></code> 掉了，
剩下的一个监视器将无限期地处于 <code class="docutils literal notranslate"><span class="pre">probing</span></code> 状态，
直到其他监视器中的一个启动。</p>
<p>如果法定人数已经建立，只要它们能够被联系到，
那么监视器守护进程应该能快速找到其他监视器。
如果监视器卡在 <code class="docutils literal notranslate"><span class="pre">probing</span></code> 状态，
并且您已经用尽了前述排查监视器之间通信故障的步骤，
那么有可能是问题监视器试图用错误的地址联系其他监视器。
<code class="docutils literal notranslate"><span class="pre">mon_status</span></code> 会输出这个监视器已知的 <code class="docutils literal notranslate"><span class="pre">monmap</span></code> ：
确定 <code class="docutils literal notranslate"><span class="pre">monmap</span></code> 中指定的其他监视器的位置是否与网络中监视器的位置相匹配。
如果不匹配，参阅 <a class="reference internal" href="#rados-troubleshooting-troubleshooting-mon-recovering-broken-monmap"><span class="std std-ref">修复监视器损坏的 monmap</span></a> 。
如果 <code class="docutils literal notranslate"><span class="pre">monmap</span></code> 中指定的监视器位置与监视器在网络中的位置一致，
那么持续的 <code class="docutils literal notranslate"><span class="pre">probing</span></code> 状态可能与监视器节点之间严重的时钟偏差有关。
参阅<a class="reference internal" href="#id7">时钟偏差</a>。如果<a class="reference internal" href="#id7">时钟偏差</a>中的信息无法使监视器摆脱 <code class="docutils literal notranslate"><span class="pre">probing</span></code> 状态，
则请准备好系统日志并向 Ceph 社区寻求帮助。
有关正确准备日志的信息，参阅<a class="reference internal" href="#id16">收集所需日志</a>。</p>
</div></blockquote>
<p><strong>监视器状态为 ``electing`` 时，是什么意思？</strong></p>
<blockquote>
<div><p>如果 <code class="docutils literal notranslate"><span class="pre">ceph</span> <span class="pre">health</span> <span class="pre">detail</span></code> 显示监视器的状态为 <code class="docutils literal notranslate"><span class="pre">electing</span></code> ，
则表示监视器们正在进行选举。选举通常会很快完成，
但有时监视器会陷入所谓的<em>选举风暴（ election storm ）</em>。
有关监视器选举的更多信息，参阅
<a class="reference internal" href="../../../dev/mon-elections/#dev-mon-elections"><span class="std std-ref">监视器选举</span></a> 。</p>
<p>选举风暴的出现可能表明监视器节点之间存在时钟偏差。
详情见<a class="reference internal" href="#id7">时钟偏差</a>。</p>
<p>如果您的时钟已正确同步，请在邮件列表和 bug tracker 中搜索与您的问题相似的问题。 <code class="docutils literal notranslate"><span class="pre">electing</span></code> 状态不太可能一直持续。
在 Cuttlefish 版之后的 Ceph 版本中，
除了时钟偏差之外，没有其他已知原因可以解释为何
<code class="docutils literal notranslate"><span class="pre">electing</span></code> 状态会持续存在。</p>
<p>如果在调查时把问题监视器置于 <code class="docutils literal notranslate"><span class="pre">down</span></code> 状态，
有可能查出它持续处于 <code class="docutils literal notranslate"><span class="pre">electing</span></code> 状态的起因。
这只有在监视器数量足以形成法定人数时才有可能。</p>
</div></blockquote>
<p><strong>监视器状态为 ``synchronizing`` 时，是什么意思？</strong></p>
<blockquote>
<div><p>如果 <code class="docutils literal notranslate"><span class="pre">ceph</span> <span class="pre">health</span> <span class="pre">detail</span></code> 显示监视器状态为 <code class="docutils literal notranslate"><span class="pre">synchronizing</span></code> （正在同步），
则表示监视器正在赶上集群的其他部分，以便加入法定人数。
监视器与其他法定人数同步所需的时间取决于集群监视器存储的大小、
集群的规模以及集群的状态。
与较小的、新集群相比，较大的和降级的集群，
它们的监视器处于 <code class="docutils literal notranslate"><span class="pre">synchronizing</span></code> 状态的时间更长。</p>
<p>监视器的状态从 <code class="docutils literal notranslate"><span class="pre">synchronizing</span></code> 变为 <code class="docutils literal notranslate"><span class="pre">electing</span></code> ，
然后又变回 <code class="docutils literal notranslate"><span class="pre">synchronizing</span></code> ，这说明了一个问题：
集群状态的变化（即生成新的映射图）可能太快了，
同步过程跟不上创建新映射图的产生速度。
这个问题在 Cuttlefish 版之前比在最近的版本中出现得更频繁，
因为从那时起，为了避免这种动态变化，同步过程经过了重构和增强。
如果您在之后的版本中遇到此问题，请在
<a class="reference external" href="https://tracker.ceph.com">Ceph bug 跟踪器</a> 中报告此问题。
准备并提供日志以证实您提出的 bug 。
有关正确准备日志的信息，参阅<a class="reference internal" href="#id16">收集所需日志</a>。</p>
</div></blockquote>
<p><strong>监视器状态为 ``leader`` 或 ``peon`` 时，是什么意思？</strong></p>
<blockquote>
<div><p>集群处于 <code class="docutils literal notranslate"><span class="pre">HEALTH_OK</span></code> 状态下的常规 Ceph 操作期间，
Ceph 集群中的一个监视器处于 <code class="docutils literal notranslate"><span class="pre">leader</span></code> 状态，
其余监视器处于 <code class="docutils literal notranslate"><span class="pre">peon</span></code> 状态。可以检查
<code class="docutils literal notranslate"><span class="pre">ceph</span> <span class="pre">tell</span> <span class="pre">&lt;mon_name&gt;</span> <span class="pre">mon_status</span></code> 命令返回的、状态键的值来确定指定监视器的状态。</p>
<p>如果 <code class="docutils literal notranslate"><span class="pre">ceph</span> <span class="pre">health</span> <span class="pre">detail</span></code> 显示监视器处于 <code class="docutils literal notranslate"><span class="pre">leader</span></code> 状态或
<code class="docutils literal notranslate"><span class="pre">peon</span></code> 状态，那么很可能存在时钟偏差。
按照<a class="reference internal" href="#id7">时钟偏差</a>中的指导进行操作。如果已经做过了那些操作，
但 <code class="docutils literal notranslate"><span class="pre">ceph</span> <span class="pre">health</span> <span class="pre">detail</span></code> 仍然显示监视器处于 <code class="docutils literal notranslate"><span class="pre">leader</span></code> 状态或
<code class="docutils literal notranslate"><span class="pre">peon</span></code> 状态，请在 <a class="reference external" href="https://tracker.ceph.com">Ceph bug 跟踪器</a> 中报告该问题。
如果您提出了问题，请提供日志以证实该问题。
有关正确准备日志的信息，参阅<a class="reference internal" href="#id16">收集所需日志</a>。</p>
</div></blockquote>
</section>
<section id="monmap">
<span id="rados-troubleshooting-troubleshooting-mon-recovering-broken-monmap"></span><h3>修复监视器损坏的 monmap<a class="headerlink" href="#monmap" title="Permalink to this heading"></a></h3>
<p>如<a class="reference internal" href="#rados-troubleshoting-troubleshooting-mon-understanding-mon-status"><span class="std std-ref">深入理解 mon_status</span></a> 所述，
可以用 <code class="docutils literal notranslate"><span class="pre">ceph</span> <span class="pre">tell</span> <span class="pre">mon.c</span> <span class="pre">mon_status</span></code> 命令来获取 monmap 。</p>
<p>下面是一个 <code class="docutils literal notranslate"><span class="pre">monmap</span></code> 的示例：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">epoch</span> <span class="mi">3</span>
<span class="n">fsid</span> <span class="mi">5</span><span class="n">c4e9d53</span><span class="o">-</span><span class="n">e2e1</span><span class="o">-</span><span class="mi">478</span><span class="n">a</span><span class="o">-</span><span class="mi">8061</span><span class="o">-</span><span class="n">f543f8be4cf8</span>
<span class="n">last_changed</span> <span class="mi">2013</span><span class="o">-</span><span class="mi">10</span><span class="o">-</span><span class="mi">30</span> <span class="mi">04</span><span class="p">:</span><span class="mi">12</span><span class="p">:</span><span class="mf">01.945629</span>
<span class="n">created</span> <span class="mi">2013</span><span class="o">-</span><span class="mi">10</span><span class="o">-</span><span class="mi">29</span> <span class="mi">14</span><span class="p">:</span><span class="mi">14</span><span class="p">:</span><span class="mf">41.914786</span>
<span class="mi">0</span><span class="p">:</span> <span class="mf">127.0.0.1</span><span class="p">:</span><span class="mi">6789</span><span class="o">/</span><span class="mi">0</span> <span class="n">mon</span><span class="o">.</span><span class="n">a</span>
<span class="mi">1</span><span class="p">:</span> <span class="mf">127.0.0.1</span><span class="p">:</span><span class="mi">6790</span><span class="o">/</span><span class="mi">0</span> <span class="n">mon</span><span class="o">.</span><span class="n">b</span>
<span class="mi">2</span><span class="p">:</span> <span class="mf">127.0.0.1</span><span class="p">:</span><span class="mi">6795</span><span class="o">/</span><span class="mi">0</span> <span class="n">mon</span><span class="o">.</span><span class="n">c</span>
</pre></div>
</div>
<p>此 <code class="docutils literal notranslate"><span class="pre">monmap</span></code> 正常，但您的 <code class="docutils literal notranslate"><span class="pre">monmap</span></code> 可能不正常。
某个节点中的 <code class="docutils literal notranslate"><span class="pre">monmap</span></code> 可能已经过时，因为该节点宕机了很长时间，
在此期间集群的监视器发生了变化。</p>
<p>更新监视器过时的 <code class="docutils literal notranslate"><span class="pre">monmap</span></code> 有两种方法：</p>
<ol class="upperalpha">
<li><p><strong>废弃这些监视器并重新部署。</strong></p>
<blockquote>
<div><p>只有在确定不会丢失已报废监视器所保存信息的情况下，
才可以这样做。确保其他监视器状态良好，
这样新监视器才能与活着的监视器们同步。记住，
如果没有监视器的其他内容副本，销毁监视器可能会导致数据丢失。</p>
</div></blockquote>
</li>
<li><p><strong>把一份 monmap 注入监视器。</strong></p>
<blockquote>
<div><p>可以这样修复监视器：从集群中活着的监视器中提取出最新的
<code class="docutils literal notranslate"><span class="pre">monmap</span></code> ，并将其注入损坏或丢失了 <code class="docutils literal notranslate"><span class="pre">monmap</span></code> 的监视器，
来修复 <code class="docutils literal notranslate"><span class="pre">monmap</span></code> 过时了的监视器。</p>
<p>执行以下步骤，施行此解决方案：</p>
<ol class="arabic">
<li><p>通过以下两种方式之一提取 <code class="docutils literal notranslate"><span class="pre">monmap</span></code> ：</p>
<ol class="loweralpha">
<li><p><strong>如果监视器们达成了法定人数：</strong></p>
<p>从法定人数提取 <code class="docutils literal notranslate"><span class="pre">monmap</span></code> ：</p>
<blockquote>
<div><div class="highlight-default notranslate"><div class="highlight"><pre><span class="prompt1">ceph<span class="w"> </span>mon<span class="w"> </span>getmap<span class="w"> </span>-o<span class="w"> </span>/tmp/monmap</span>
</pre></div></div></div></blockquote>
</li>
<li><p><strong>如果监视器们没有达成法定人数：</strong></p>
<p>直接从已经停机的监视器提取 <code class="docutils literal notranslate"><span class="pre">monmap</span></code> ：</p>
<blockquote>
<div><div class="highlight-default notranslate"><div class="highlight"><pre><span class="prompt1">ceph-mon<span class="w"> </span>-i<span class="w"> </span>ID-FOO<span class="w"> </span>--extract-monmap<span class="w"> </span>/tmp/monmap</span>
</pre></div></div></div></blockquote>
<p>在本例中，已停机的监视器的 ID 是 <code class="docutils literal notranslate"><span class="pre">ID-FOO</span></code> 。</p>
</li>
</ol>
</li>
<li><p>停掉要注入 <code class="docutils literal notranslate"><span class="pre">monmap</span></code> 的那个监视器：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span class="prompt1">service<span class="w"> </span>ceph<span class="w"> </span>-a<span class="w"> </span>stop<span class="w"> </span>mon.<span class="o">{</span>mon-id<span class="o">}</span></span>
</pre></div></div></li>
<li><p>把 monmap 注入已停掉的监视器：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span class="prompt1">ceph-mon<span class="w"> </span>-i<span class="w"> </span>ID<span class="w"> </span>--inject-monmap<span class="w"> </span>/tmp/monmap</span>
</pre></div></div></li>
<li><p>启动这个监视器。</p>
<div class="admonition warning">
<p class="admonition-title">Warning</p>
<p>向监视器注入 <code class="docutils literal notranslate"><span class="pre">monmap</span></code> 可能会导致严重问题。
注入 <code class="docutils literal notranslate"><span class="pre">monmap</span></code> 会覆盖监视器上存储的最新 <code class="docutils literal notranslate"><span class="pre">monmap</span></code> 。
务必小心！</p>
</div>
</li>
</ol>
</div></blockquote>
</li>
</ol>
</section>
<section id="id7">
<h3>时钟偏差<a class="headerlink" href="#id7" title="Permalink to this heading"></a></h3>
<p>Paxos 共识算法需要严格的时间同步，这意味着法定人数内部、
监视器之间的时钟偏差会对监视器的运行产生严重影响。
由此产生的行为可能会令人费解。为避免这一问题，
需要在监视器节点上运行时钟同步工具：例如，
用 <code class="docutils literal notranslate"><span class="pre">Chrony</span></code> 或传统的 <code class="docutils literal notranslate"><span class="pre">ntpd</span></code> 工具。配置每个监视器节点，
使 <cite>iburst</cite> 选项生效，这样每个监视器就有多个对等节点，
包括以下内容：</p>
<ul class="simple">
<li><p>相互之间</p></li>
<li><p>内部 <code class="docutils literal notranslate"><span class="pre">NTP</span></code> 服务器</p></li>
<li><p>多个外部的、公用的 pool 服务器</p></li>
</ul>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p><code class="docutils literal notranslate"><span class="pre">iburst</span></code> 选项会一次发送八个数据包组成的一组数据包，
而不是通常的单个数据包，
在让两个节点进行初始同步时会这样运行。</p>
</div>
<p>此外，最好将集群中的 <em>所有</em> 节点与内部和外部服务器同步，
甚至可能与监视器同步。要在物理裸机上运行 <code class="docutils literal notranslate"><span class="pre">NTP</span></code> 服务器：
VM 的虚拟化时钟不适合用于稳定的计时。
有关网络时间协议 (NTP) 的更多信息，
参阅 <a class="reference external" href="https://www.ntp.org">https://www.ntp.org</a> 。
您的组织可能已经有了高质量的内部 <code class="docutils literal notranslate"><span class="pre">NTP</span></code> 服务器。
<code class="docutils literal notranslate"><span class="pre">NTP</span></code> 服务器设备的来源有以下几种：</p>
<ul class="simple">
<li><p>Microsemi (之前叫 Symmetricom) <a class="reference external" href="https://www.microsemi.com/product-directory/3425-timing-synchronization">https://microsemi.com</a></p></li>
<li><p>EndRun <a class="reference external" href="https://endruntechnologies.com/products/ntp-time-servers">https://endruntechnologies.com</a></p></li>
<li><p>Netburner <a class="reference external" href="https://www.netburner.com/products/network-time-server/pk70-ex-ntp-network-time-server">https://www.netburner.com</a></p></li>
</ul>
<section id="id8">
<h4>时钟偏差问答<a class="headerlink" href="#id8" title="Permalink to this heading"></a></h4>
<p><strong>容许的最大时钟偏差量是多少？</strong></p>
<blockquote>
<div><p>默认情况下，监视器允许时钟偏差最多 0.05 秒（ 50 毫秒）。</p>
</div></blockquote>
<p><strong>我可以增大容许的最大时钟偏差吗？</strong></p>
<blockquote>
<div><p>可以，但我们强烈建议不要这样做。允许的最大时钟偏差可通过
<code class="docutils literal notranslate"><span class="pre">mon-clock-drift-allowed</span></code> （允许的时钟偏差）
选项进行配置，但更改此选项差不多肯定是个馊主意。
之所以设置最大时钟偏差，是因为发生了时钟偏差的监视器不再可靠。
目前的默认值已经证明了其价值，
就是在监视器出现严重问题之前向用户发出警报。
更改此值可能会对监视器的稳定性、
和整个集群的健康状况造成不可预见的影响。</p>
</div></blockquote>
<p><strong>我如何判断是否出现了时钟偏差？</strong></p>
<blockquote>
<div><p>监视器会通过集群状态 <code class="docutils literal notranslate"><span class="pre">HEALTH_WARN</span></code> 警告你。
出现时钟偏差时， <code class="docutils literal notranslate"><span class="pre">ceph</span> <span class="pre">health</span> <span class="pre">detail</span></code> 和 <code class="docutils literal notranslate"><span class="pre">ceph</span> <span class="pre">status</span></code>
命令会返回类似下面的输出：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">mon</span><span class="o">.</span><span class="n">c</span> <span class="n">addr</span> <span class="mf">10.10.0.1</span><span class="p">:</span><span class="mi">6789</span><span class="o">/</span><span class="mi">0</span> <span class="n">clock</span> <span class="n">skew</span> <span class="mf">0.08235</span><span class="n">s</span> <span class="o">&gt;</span> <span class="nb">max</span> <span class="mf">0.05</span><span class="n">s</span> <span class="p">(</span><span class="n">latency</span> <span class="mf">0.0045</span><span class="n">s</span><span class="p">)</span>
</pre></div>
</div>
<p>在本例中，监视器 <code class="docutils literal notranslate"><span class="pre">mon.c</span></code> 被标记为遭遇了时钟偏差。</p>
<p>在 Luminous 及其后续版本中，可以执行
<code class="docutils literal notranslate"><span class="pre">ceph</span> <span class="pre">time-sync-status</span></code> 命令来检查时钟偏差。
注意， lead 监视器通常拥有数值最小的 IP 地址。
它将始终显示 <code class="docutils literal notranslate"><span class="pre">0</span></code> ：其他监视器报告的偏移量是相对于 lead 监视器的，
而不是相对于哪一个外部源的。</p>
</div></blockquote>
<p><strong>如果出现了时钟偏差，我该怎么办？</strong></p>
<blockquote>
<div><p>同步时钟。可能要靠 NTP 客户端。不过，
如果您已经在使用 NTP 客户端，但仍遇到时钟偏差问题，
请确定您使用的 NTP 服务器是位于远程网络的还是托管在您自己的网络上。
搭建自己的 NTP 服务器往往能减轻时钟偏差问题。</p>
</div></blockquote>
</section>
</section>
<section id="id9">
<h3>客户端不能连接或挂载<a class="headerlink" href="#id9" title="Permalink to this heading"></a></h3>
<p>如果一个客户端不能连接到集群或不能挂载，检查防火墙配置。
有些操作系统安装工具把 <code class="docutils literal notranslate"><span class="pre">REJECT</span></code> 规则加入了 <code class="docutils literal notranslate"><span class="pre">iptables</span></code> ，
它会拒绝除 <code class="docutils literal notranslate"><span class="pre">ssh</span></code> 以外的所有入栈连接。
如果你的监视器主机的 iptables 有这样的 <code class="docutils literal notranslate"><span class="pre">REJECT</span></code> 规则，
别的客户端进来的连接就会失败，进而导致超时错误。
得先找到拒绝客户端连接 Ceph 守护进程的 <code class="docutils literal notranslate"><span class="pre">iptables</span></code> 规则。
例如：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">REJECT</span> <span class="nb">all</span> <span class="o">--</span> <span class="n">anywhere</span> <span class="n">anywhere</span> <span class="n">reject</span><span class="o">-</span><span class="k">with</span> <span class="n">icmp</span><span class="o">-</span><span class="n">host</span><span class="o">-</span><span class="n">prohibited</span>
</pre></div>
</div>
<p>你也许还要在 Ceph 主机上增加 iptables 规则来放通 Ceph 监视器的 TCP 端口（默认是 6789 端口）、
和 Ceph OSD 端口（默认从 6800 到 7568 ）。例如：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">iptables</span> <span class="o">-</span><span class="n">A</span> <span class="n">INPUT</span> <span class="o">-</span><span class="n">m</span> <span class="n">multiport</span> <span class="o">-</span><span class="n">p</span> <span class="n">tcp</span> <span class="o">-</span><span class="n">s</span> <span class="p">{</span><span class="n">ip</span><span class="o">-</span><span class="n">address</span><span class="p">}</span><span class="o">/</span><span class="p">{</span><span class="n">netmask</span><span class="p">}</span> <span class="o">--</span><span class="n">dports</span> <span class="mi">6789</span><span class="p">,</span><span class="mi">6800</span><span class="p">:</span><span class="mi">7300</span> <span class="o">-</span><span class="n">j</span> <span class="n">ACCEPT</span>
</pre></div>
</div>
</section>
</section>
<section id="id10">
<h2>监视器存储故障<a class="headerlink" href="#id10" title="Permalink to this heading"></a></h2>
<section id="id11">
<h3>存储损坏的症状<a class="headerlink" href="#id11" title="Permalink to this heading"></a></h3>
<p>Ceph 监视器把<a class="reference internal" href="../../../glossary/#term-32"><span class="xref std std-term">集群运行图</span></a>存储在键值数据库里。如果某个监视器由于键值存储损坏而发生故障，监视器日志里可能出现如下错误消息：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Corruption</span><span class="p">:</span> <span class="n">error</span> <span class="ow">in</span> <span class="n">middle</span> <span class="n">of</span> <span class="n">record</span>
</pre></div>
</div>
<p>或者：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Corruption</span><span class="p">:</span> <span class="mi">1</span> <span class="n">missing</span> <span class="n">files</span><span class="p">;</span> <span class="n">e</span><span class="o">.</span><span class="n">g</span><span class="o">.</span><span class="p">:</span> <span class="o">/</span><span class="n">var</span><span class="o">/</span><span class="n">lib</span><span class="o">/</span><span class="n">ceph</span><span class="o">/</span><span class="n">mon</span><span class="o">/</span><span class="n">mon</span><span class="o">.</span><span class="n">foo</span><span class="o">/</span><span class="n">store</span><span class="o">.</span><span class="n">db</span><span class="o">/</span><span class="mf">1234567.</span><span class="n">ldb</span>
</pre></div>
</div>
</section>
<section id="id12">
<h3>用健康的监视器恢复<a class="headerlink" href="#id12" title="Permalink to this heading"></a></h3>
<p>如果集群内还有幸存的监视器，就可以用新监视器<a class="reference internal" href="../../operations/add-or-rm-mons/#adding-and-removing-monitors"><span class="std std-ref">替换掉</span></a>损坏的。新监视器启动后，
会与健康节点同步。新监视器完全同步后，就可以服务客户端了。</p>
</section>
<section id="osd">
<span id="mon-store-recovery-using-osds"></span><h3>用 OSD 恢复<a class="headerlink" href="#osd" title="Permalink to this heading"></a></h3>
<p>即使所有监视器同时发生故障，仍然有可能通过存储在 OSD 中的信息来恢复监视器的存储。
我们鼓励您在一个 Ceph 集群中至少部署三个（最好是五个）监视器。
在这样的部署中，监视器不太可能全部发生故障。但是，
数据中心意外断电，同时磁盘配备或文件系统选项配置不当，
可能会导致底层文件系统故障，并导致所有监视器瘫痪。
在这种情况下，可以用 OSD 中的数据来恢复监视器。
下面是个脚本，可用于在这种情况下恢复监视器：</p>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span><span class="nv">ms</span><span class="o">=</span>/root/mon-store
mkdir<span class="w"> </span><span class="nv">$ms</span>

<span class="c1"># 从已关停的 OSD 收集集群运行图</span>
<span class="k">for</span><span class="w"> </span>host<span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="nv">$hosts</span><span class="p">;</span><span class="w"> </span><span class="k">do</span>
<span class="w">  </span>rsync<span class="w"> </span>-avz<span class="w"> </span><span class="nv">$ms</span>/.<span class="w"> </span>user@<span class="nv">$host</span>:<span class="nv">$ms</span>.remote
<span class="w">  </span>rm<span class="w"> </span>-rf<span class="w"> </span><span class="nv">$ms</span>
<span class="w">  </span>ssh<span class="w"> </span>user@<span class="nv">$host</span><span class="w"> </span><span class="s">&lt;&lt;EOF</span>
<span class="s">    for osd in /var/lib/ceph/osd/ceph-*; do</span>
<span class="s">      ceph-objectstore-tool --data-path \$osd --no-mon-config --op update-mon-db --mon-store-path $ms.remote</span>
<span class="s">    done</span>
<span class="s">EOF</span>
<span class="w">  </span>rsync<span class="w"> </span>-avz<span class="w"> </span>user@<span class="nv">$host</span>:<span class="nv">$ms</span>.remote/.<span class="w"> </span><span class="nv">$ms</span>
<span class="k">done</span>

<span class="c1"># 用收集来的运行图重建监视器存储，如果集群没用 cephx 认证，\</span>
<span class="c1"># 我们可以跳过更新密钥环的步骤，也不用加 --keyring 选项了，\</span>
<span class="c1"># 就是说可以直接运行 ``ceph-monstore-tool $ms rebuild``</span>
ceph-authtool<span class="w"> </span>/path/to/admin.keyring<span class="w"> </span>-n<span class="w"> </span>mon.<span class="w"> </span><span class="se">\</span>
<span class="w">  </span>--cap<span class="w"> </span>mon<span class="w"> </span><span class="s1">&#39;allow *&#39;</span>
ceph-authtool<span class="w"> </span>/path/to/admin.keyring<span class="w"> </span>-n<span class="w"> </span>client.admin<span class="w"> </span><span class="se">\</span>
<span class="w">  </span>--cap<span class="w"> </span>mon<span class="w"> </span><span class="s1">&#39;allow *&#39;</span><span class="w"> </span>--cap<span class="w"> </span>osd<span class="w"> </span><span class="s1">&#39;allow *&#39;</span><span class="w"> </span>--cap<span class="w"> </span>mds<span class="w"> </span><span class="s1">&#39;allow *&#39;</span>
<span class="c1"># add one or more ceph-mgr&#39;s key to the keyring. in this case, an encoded key</span>
<span class="c1"># for mgr.x is added, you can find the encoded key in</span>
<span class="c1"># /etc/ceph/${cluster}.${mgr_name}.keyring on the machine where ceph-mgr is</span>
<span class="c1"># deployed</span>
ceph-authtool<span class="w"> </span>/path/to/admin.keyring<span class="w"> </span>--add-key<span class="w"> </span><span class="s1">&#39;AQDN8kBe9PLWARAAZwxXMr+n85SBYbSlLcZnMA==&#39;</span><span class="w"> </span>-n<span class="w"> </span>mgr.x<span class="w"> </span><span class="se">\</span>
<span class="w">  </span>--cap<span class="w"> </span>mon<span class="w"> </span><span class="s1">&#39;allow profile mgr&#39;</span><span class="w"> </span>--cap<span class="w"> </span>osd<span class="w"> </span><span class="s1">&#39;allow *&#39;</span><span class="w"> </span>--cap<span class="w"> </span>mds<span class="w"> </span><span class="s1">&#39;allow *&#39;</span>
<span class="c1"># If your monitors&#39; ids are not sorted by ip address, please specify them in order.</span>
<span class="c1"># For example. if mon &#39;a&#39; is 10.0.0.3, mon &#39;b&#39; is 10.0.0.2, and mon &#39;c&#39; is  10.0.0.4,</span>
<span class="c1"># please passing &quot;--mon-ids b a c&quot;.</span>
<span class="c1"># In addition, if your monitors&#39; ids are not single characters like &#39;a&#39;, &#39;b&#39;, &#39;c&#39;, please</span>
<span class="c1"># specify them in the command line by passing them as arguments of the &quot;--mon-ids&quot;</span>
<span class="c1"># option. if you are not sure, please check your ceph.conf to see if there is any</span>
<span class="c1"># sections named like &#39;[mon.foo]&#39;. don&#39;t pass the &quot;--mon-ids&quot; option, if you are</span>
<span class="c1"># using DNS SRV for looking up monitors.</span>
ceph-monstore-tool<span class="w"> </span><span class="nv">$ms</span><span class="w"> </span>rebuild<span class="w"> </span>--<span class="w"> </span>--keyring<span class="w"> </span>/path/to/admin.keyring<span class="w"> </span>--mon-ids<span class="w"> </span>alpha<span class="w"> </span>beta<span class="w"> </span>gamma

<span class="c1"># 备份一下损坏的 store.db 以防万一！</span>
<span class="c1"># 所有监视器上都要备份一下。</span>
mv<span class="w"> </span>/var/lib/ceph/mon/mon.foo/store.db<span class="w"> </span>/var/lib/ceph/mon/mon.foo/store.db.corrupted

<span class="c1"># move rebuild store.db into place.  repeat for all monitors.</span>
mv<span class="w"> </span><span class="nv">$ms</span>/store.db<span class="w"> </span>/var/lib/ceph/mon/mon.foo/store.db
chown<span class="w"> </span>-R<span class="w"> </span>ceph:ceph<span class="w"> </span>/var/lib/ceph/mon/mon.foo/store.db
</pre></div>
</div>
<p>此脚本会执行下列步骤：</p>
<ol class="arabic simple">
<li><p>从所有 OSD 收集映射图</p></li>
<li><p>然后重建监视器存储</p></li>
<li><p>把各项目加进密钥环文件，并分配相应的能力</p></li>
<li><p>用恢复好的副本替换 <code class="docutils literal notranslate"><span class="pre">mon.foo</span></code> 上损坏的存储。</p></li>
</ol>
<section id="id13">
<h4>已知的局限性<a class="headerlink" href="#id13" title="Permalink to this heading"></a></h4>
<p>上述恢复工具无法恢复以下信息：</p>
<ul class="simple">
<li><p><strong>某些加过的密钥环</strong>：所有用 <code class="docutils literal notranslate"><span class="pre">ceph</span> <span class="pre">auth</span> <span class="pre">add</span></code> 命令加上的
OSD 密钥环都从 OSD 副本中恢复了； <code class="docutils literal notranslate"><span class="pre">client.admin</span></code> 密钥环也用
<code class="docutils literal notranslate"><span class="pre">ceph-monstore-tool</span></code> 导入了。但是，在已恢复的监视器存储中，
MDS 密钥环和其它所有密钥环都会丢失，你也许得手动重加。</p></li>
<li><p><strong>正在创建的存储池</strong>: 如果有过正在创建的 RADOS 存储池，
那些状态会丢失。恢复工具操作时假定：所有存储池都已创建。
如果在没创建完的存储池恢复后，有 PG 卡在 <code class="docutils literal notranslate"><span class="pre">unknown</span></code> 状态，
可以运行 <code class="docutils literal notranslate"><span class="pre">ceph</span> <span class="pre">osd</span> <span class="pre">force-create-pg</span></code> 命令强制创建 <em>空</em> PG 。
此命令会创建一个 <em>空</em> PG ，因此确定存储池为空时才可以执行此操作。
（译者：否则可能清空此 PG ）</p></li>
<li><p><strong>MDS 映射图</strong>： MDS 的各种映射图会丢失。</p></li>
</ul>
</section>
</section>
</section>
<section id="id14">
<h2>所有尝试都失败了，怎么办？<a class="headerlink" href="#id14" title="Permalink to this heading"></a></h2>
<section id="id15">
<h3>到外面寻求帮助<a class="headerlink" href="#id15" title="Permalink to this heading"></a></h3>
<p>您可以在 OFTC（服务器 irc.oftc.net）上的 #ceph 和 #ceph-devel IRC 频道中，
或在 <code class="docutils literal notranslate"><span class="pre">dev&#64;ceph.io</span></code> 和 <code class="docutils literal notranslate"><span class="pre">ceph-users&#64;lists.ceph.com</span></code> 中寻求帮助。
先准备好日志，并在发出请求时将其准备就绪。</p>
<p>可以通过这个地址加入上游 Ceph Slack 工作区：
<a class="reference external" href="https://ceph-storage.slack.com/">https://ceph-storage.slack.com/</a></p>
<p>与上游 Ceph 社区取得联系的最新信息（截至 2023 年 12 月），
参见 <a class="reference external" href="https://ceph.io/en/community/connect/">https://ceph.io/en/community/connect/</a> 。</p>
</section>
<section id="id16">
<h3>收集所需日志<a class="headerlink" href="#id16" title="Permalink to this heading"></a></h3>
<p>监视器日志的默认位置是 <code class="docutils literal notranslate"><span class="pre">/var/log/ceph/ceph-mon.FOO.log*</span></code> 。
监视器日志的位置可能已经改了，不是默认位置。
如果监视器日志不在默认位置，可执行以下命令查找监视器日志的位置：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span class="prompt1">ceph-conf<span class="w"> </span>--name<span class="w"> </span>mon.FOO<span class="w"> </span>--show-config-value<span class="w"> </span>log_file</span>
</pre></div></div><p>日志中的信息量由集群配置文件中的调试级别决定。
如果 Ceph 在用的是默认调试级别，
那么您的日志可能会错过重要信息，
这些信息有助于上游 Ceph 社区定位问题。</p>
<p>提高调试级别以确保监视器日志包含相关信息。
在此，我们对来自监视器的信息感兴趣。
与其他组件一样，监视器也有不同的部分，
输出不同子系统的调试信息。</p>
<p>如果您是一位经验丰富的 Ceph 故障排除者，我们建议您提高最相关子系统的调试级别。
这种方法对初学者来说可能不太容易。但在大多数情况下，
如果输入以下调试级别，就能记录足够的信息来定位问题：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">debug_mon</span> <span class="o">=</span> <span class="mi">10</span>
<span class="n">debug_ms</span> <span class="o">=</span> <span class="mi">1</span>
</pre></div>
</div>
<p>有时，这些调试级别没能产生足够的信息。在这种情况下，
上游 Ceph 社区成员会让您对这些或其他调试级别进行额外更改。
无论如何，对我们来说，收到一些有用的信息总比收到空日志要好。</p>
</section>
<section id="id17">
<h3>我需要重启监视器来更改调试级别吗？<a class="headerlink" href="#id17" title="Permalink to this heading"></a></h3>
<p>不需要。更改监视器的调试级别时没必要重启它。</p>
<p>更改调试级别有两种方法。一种方法是在有法定人数时使用。
另一种方法是在没有法定人数时使用。</p>
<p><strong>有法定人数时更改调试级别</strong></p>
<blockquote>
<div><p>把调试选项注入需要调试的指定监视器:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">ceph</span> <span class="n">tell</span> <span class="n">mon</span><span class="o">.</span><span class="n">FOO</span> <span class="n">config</span> <span class="nb">set</span> <span class="n">debug_mon</span> <span class="mi">10</span><span class="o">/</span><span class="mi">10</span>
</pre></div>
</div>
<p>或者一次性注入所有监视器：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">ceph</span> <span class="n">tell</span> <span class="n">mon</span><span class="o">.*</span> <span class="n">config</span> <span class="nb">set</span> <span class="n">debug_mon</span> <span class="mi">10</span><span class="o">/</span><span class="mi">10</span>
</pre></div>
</div>
</div></blockquote>
<p><strong>没有法定人数时更改调试级别</strong></p>
<blockquote>
<div><p>使用需要调试的指定监视器的管理套接字，
直接调整这个监视器的配置选项：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">ceph</span> <span class="n">daemon</span> <span class="n">mon</span><span class="o">.</span><span class="n">FOO</span> <span class="n">config</span> <span class="nb">set</span> <span class="n">debug_mon</span> <span class="mi">10</span><span class="o">/</span><span class="mi">10</span>
</pre></div>
</div>
</div></blockquote>
<p><strong>把调试级别恢复成它的默认值</strong></p>
<p>要把调试级别恢复成默认值，应该用调试级别 <code class="docutils literal notranslate"><span class="pre">1/10</span></code>
而不是调试级别 <code class="docutils literal notranslate"><span class="pre">10/10</span></code> 运行上述命令。
要检查监视器的当前值，用管理套接字并运行下列任一命令：</p>
<blockquote>
<div><div class="highlight-default notranslate"><div class="highlight"><pre><span class="prompt1">ceph<span class="w"> </span>daemon<span class="w"> </span>mon.FOO<span class="w"> </span>config<span class="w"> </span>show</span>
</pre></div></div></div></blockquote>
<p>或者：</p>
<blockquote>
<div><div class="highlight-default notranslate"><div class="highlight"><pre><span class="prompt1">ceph<span class="w"> </span>daemon<span class="w"> </span>mon.FOO<span class="w"> </span>config<span class="w"> </span>get<span class="w"> </span><span class="s1">&#39;OPTION_NAME&#39;</span></span>
</pre></div></div></div></blockquote>
</section>
<section id="id18">
<h3>我在某个调试级别下重现了问题，然后呢？<a class="headerlink" href="#id18" title="Permalink to this heading"></a></h3>
<p>只需向上游 Ceph 社区发送日志中与监视器问题相关的部分即可。
由于确定哪些部分是相关的并不容易，
因此上游 Ceph 社区接受完整且未经删节的日志。
但不要发送包含成千上万行且没有额外说明的日志。
有助于让 Ceph 社区帮助您的一个常识性方法是，
记下您重现问题当时的时间和日期，
然后根据此信息提取日志对应部分的内容。</p>
<p>联系上游 Ceph 社区，可以在邮件列表、 IRC 或 Slack 上、
或在 <a class="reference external" href="http://tracker.ceph.com/projects/ceph/issues/new">tracker</a> 上提交新问题。</p>
</section>
</section>
</section>



<div id="support-the-ceph-foundation" class="admonition note">
  <p class="first admonition-title">Brought to you by the Ceph Foundation</p>
  <p class="last">The Ceph Documentation is a community resource funded and hosted by the non-profit <a href="https://ceph.io/en/foundation/">Ceph Foundation</a>. If you would like to support this and our other efforts, please consider <a href="https://ceph.io/en/foundation/join/">joining now</a>.</p>
</div>


           </div>
           
          </div>
          <footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer">
        <a href="../community/" class="btn btn-neutral float-left" title="Ceph 社区" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
        <a href="../troubleshooting-osd/" class="btn btn-neutral float-right" title="OSD 故障排除" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
    </div>

  <hr/>

  <div role="contentinfo">
    <p>&#169; Copyright 2016, Ceph authors and contributors. Licensed under Creative Commons Attribution Share Alike 3.0 (CC-BY-SA-3.0).</p>
  </div>

   

</footer>
        </div>
      </div>

    </section>

  </div>
  

  <script type="text/javascript">
      jQuery(function () {
          SphinxRtdTheme.Navigation.enable(true);
      });
  </script>

  
  
    
   

</body>
</html>